package com.seven.leetcode.problems;

/**
 * 1006. 笨阶乘
 * https://leetcode-cn.com/problems/clumsy-factorial/
 * 级别：Medium
 * <p>
 * 通常，正整数 n 的阶乘是所有小于或等于 n 的正整数的乘积。例如，factorial(10) = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1。
 * <p>
 * 相反，我们设计了一个笨阶乘 clumsy：在整数的递减序列中，我们以一个固定顺序的操作符序列来依次替换原有的乘法操作符：乘法(*)，除法(/)，加法(+)和减法(-)。
 * <p>
 * 例如，clumsy(10) = 10 * 9 / 8 + 7 - 6 * 5 / 4 + 3 - 2 *
 * 1。然而，这些运算仍然使用通常的算术运算顺序：我们在任何加、减步骤之前执行所有的乘法和除法步骤，并且按从左到右处理乘法和除法步骤。
 * <p>
 * 另外，我们使用的除法是地板除法（floor division），所以10 * 9 / 8等于11。这保证结果是一个整数。
 * <p>
 * 实现上面定义的笨函数：给定一个整数 N，它返回 N 的笨阶乘。
 * <p>
 * 示例 1：
 * <p>
 * 输入：4
 * 输出：7
 * 解释：7 = 4 * 3 / 2 + 1
 * 示例 2：
 * <p>
 * 输入：10
 * 输出：12
 * 解释：12 = 10 * 9 / 8 + 7 - 6 * 5 / 4 + 3 - 2 * 1
 *
 * @author : wenguang
 * @date : 2021/3/22 9:26
 */
public class ClumsyFactorial {

    public static void main(String[] args) {
        int target = 40;
        System.out.println("in: \ntarget->" + target);
        int result = clumsyFactorial(target);
        System.out.println("out: " + result);
    }

    public static int clumsyFactorial(int N) {
        if (N <= 0) {
            return 0;
        }

        int i1 = (N - 1) > 0 ? N - 1 : 1;
        int i2 = (N - 2) > 0 ? N - 2 : 1;
        int i3 = Math.max((N - 3), 0);

        int res = N * i1 / i2 + i3;
        int i = N - 4;
        for (; i > 3; i = i - 4) {
            i1 = i - 1;
            i2 = i - 2;
            i3 = i - 3;

            res -= (i * i1 / i2);
            res += i3;
        }

        if (i > 0) {
            i1 = (i - 1) > 0 ? i - 1 : 1;
            i2 = (i - 2) > 0 ? i - 2 : 1;
            res -= (i * i1 / i2);
        }

        return res;
    }
}
